package com.lsk.util;


import net.sf.ezmorph.MorpherRegistry;
import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;
import net.sf.json.util.JSONUtils;
import net.sf.json.xml.XMLSerializer;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Json工具类
 * @author LiuQi
 *
 */
public class JsonUtil {

    /**
     * 设置日期转换格式
     */
    static {
        // 注册器
        MorpherRegistry mr = JSONUtils.getMorpherRegistry();

        // 可转换的日期格式，即Json串中可以出现以下格式的日期与时间
        DateMorpher dm = new DateMorpher(new String[] { "yyyy",
                "yyyy-MM-dd", "yyyyMMdd",
                "yyyy-MM-dd HH:mm:ss", "yyyyMMddHHmmss"});
        mr.registerMorpher(dm);
    }

    /**
     * 从json串转换成实体对象
     *
     * @param jsonObjStr
     * @param clazz
     * @return
     */
    public static Object getDtoFromJsonObjStr(String jsonObjStr, Class<?> clazz) {
        return JSONObject.toBean(JSONObject.fromObject(jsonObjStr), clazz);
    }

    /**
     * 从json串转换成实体对象，并且实体集合属性存有另外实体Bean
     *
     * @param jsonObjStr
     * @param clazz
     * @param classMap
     * @return Object
     */
    public static Object getDtoFromJsonObjStr(String jsonObjStr, Class<?> clazz,
                                              Map<?, ?> classMap) {
        return JSONObject.toBean(JSONObject.fromObject(jsonObjStr), clazz,
                classMap);
    }

    /**
     * 把一个json数组串转换成普通数组
     *
     * @param jsonArrStr
     * @return Object[]
     */
    public static Object[] getArrFromJsonArrStr(String jsonArrStr) {
        return JSONArray.fromObject(jsonArrStr).toArray();
    }

    /**
     * 把一个json数组串转换成实体数组
     *
     * @param jsonArrStr
     * @param clazz
     * @return Object[]
     */
    public static Object[] getDtoArrFromJsonArrStr(String jsonArrStr,
                                                   Class<?> clazz) {
        JSONArray jsonArr = JSONArray.fromObject(jsonArrStr);
        Object[] objArr = new Object[jsonArr.size()];
        for (int i = 0; i < jsonArr.size(); i++) {
            objArr[i] = JSONObject.toBean(jsonArr.getJSONObject(i), clazz);
        }
        return objArr;
    }

    /**
     * 把一个json数组串转换成实体数组，且数组元素的属性含有另外实例Bean
     *
     * @param jsonArrStr
     * @param clazz
     * @param classMap
     * @return Object[]
     */
    public static Object[] getDtoArrFromJsonArrStr(String jsonArrStr,
                                                   Class<?> clazz, Map<?, ?> classMap) {
        JSONArray array = JSONArray.fromObject(jsonArrStr);
        Object[] obj = new Object[array.size()];
        for (int i = 0; i < array.size(); i++) {
            JSONObject jsonObject = array.getJSONObject(i);
            obj[i] = JSONObject.toBean(jsonObject, clazz, classMap);
        }
        return obj;
    }

    /**
     * 把一个json数组串转换成存放普通类型元素的集合
     *
     * @param jsonArrStr
     * @return List
     */
    public static List<Object> getListFromJsonArrStr(String jsonArrStr) {
        JSONArray jsonArr = JSONArray.fromObject(jsonArrStr);
        List<Object> list = new ArrayList<Object>();
        for (int i = 0; i < jsonArr.size(); i++) {
            list.add(jsonArr.get(i));
        }
        return list;
    }

    /**
     * 把一个json数组串转换成集合，且集合里存放的为实例Bean
     *
     * @param jsonArrStr
     * @param clazz
     * @return List
     */
    public static List<Object> getListFromJsonArrStr(String jsonArrStr, Class<?> clazz) {
        JSONArray jsonArr = JSONArray.fromObject(jsonArrStr);
        List<Object> list = new ArrayList<Object>();
        for (int i = 0; i < jsonArr.size(); i++) {
            list.add(JSONObject.toBean(jsonArr.getJSONObject(i), clazz));
        }
        return list;
    }

    /**
     * 把一个json数组串转换成集合，且集合里的对象的属性含有另外实例Bean
     *
     * @param jsonArrStr
     * @param clazz
     * @param classMap
     * @return List
     */
    public static List<Object> getListFromJsonArrStr(String jsonArrStr, Class<?> clazz,
                                                     Map<?, ?> classMap) {
        JSONArray jsonArr = JSONArray.fromObject(jsonArrStr);
        List<Object> list = new ArrayList<Object>();
        for (int i = 0; i < jsonArr.size(); i++) {
            list.add(JSONObject.toBean(jsonArr.getJSONObject(i), clazz,
                    classMap));
        }
        return list;
    }

    /**
     * 把json对象串转换成map对象
     *
     * @param jsonObjStr
     * @return Map
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> getMapFromJsonObjStr(String jsonObjStr) {
        JSONObject jsonObject = JSONObject.fromObject(jsonObjStr);

        Map<String, Object> map = new HashMap<String, Object>();
        for (Iterator<String> iter = jsonObject.keys(); iter.hasNext();) {
            String key = iter.next();
            map.put(key, jsonObject.get(key));
        }
        return map;
    }

    /**
     * 把json对象串转换成map对象，且map对象里存放的为其他实体Bean
     *
     * @param jsonObjStr
     * @param clazz
     * @return Map
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> getMapFromJsonObjStr(String jsonObjStr, Class<?> clazz) {
        JSONObject jsonObject = JSONObject.fromObject(jsonObjStr);

        Map<String, Object> map = new HashMap<String, Object>();
        for (Iterator<String> iter = jsonObject.keys(); iter.hasNext();) {
            String key = iter.next();
            map.put(key,
                    JSONObject.toBean(jsonObject.getJSONObject(key), clazz));
        }
        return map;
    }

    /**
     * 把json对象串转换成map对象，且map对象里存放的其他实体Bean还含有另外实体Bean
     *
     * @param jsonObjStr
     * @param clazz
     * @param classMap
     * @return Map
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> getMapFromJsonObjStr(String jsonObjStr,
                                                           Class<?> clazz, Map<?, ?> classMap) {
        JSONObject jsonObject = JSONObject.fromObject(jsonObjStr);

        Map<String, Object> map = new HashMap<String, Object>();
        for (Iterator<String> iter = jsonObject.keys(); iter.hasNext();) {
            String key = iter.next();
            map.put(key, JSONObject.toBean(jsonObject.getJSONObject(key),
                    clazz, classMap));
        }
        return map;
    }

    /**
     * 把实体Bean、Map对象、数组、列表集合转换成Json串
     *
     * @param obj
     * @return
     * @throws Exception
     *
     */
    public static String getJsonStr(Object obj) {
        String jsonStr = null;
        // Json配置
        JsonConfig jsonCfg = new JsonConfig();
        // 注册日期处理器
        jsonCfg.registerJsonValueProcessor(Date.class,
                new JsonDateValueProcessor("yyyyMMddHHmmss"));
        if (obj == null) {
            return "{}";
        }

        if (obj instanceof Collection || obj instanceof Object[]) {
            jsonStr = JSONArray.fromObject(obj, jsonCfg).toString();
        } else {
            jsonStr = JSONObject.fromObject(obj, jsonCfg).toString();
        }

        return jsonStr;
    }

    /**
     * 把json串、数组、集合(collection map)、实体Bean转换成XML XML
     *
     * @param obj
     * @return
     * @throws Exception
     *
     */
    public static String getXMLFromObj(Object obj) {
        XMLSerializer xmlSerial = new XMLSerializer();

        // Json配置
        JsonConfig jsonCfg = new JsonConfig();

        // 注册日期处理器
        jsonCfg.registerJsonValueProcessor(Date.class,
                new JsonDateValueProcessor("yyyyMMddHHmmss"));

        if ((String.class.isInstance(obj) && String.valueOf(obj)
                .startsWith("["))
                || obj.getClass().isArray()
                || Collection.class.isInstance(obj)) {
            JSONArray jsonArr = JSONArray.fromObject(obj, jsonCfg);
            return xmlSerial.write(jsonArr);
        } else {
            JSONObject jsonObj = JSONObject.fromObject(obj, jsonCfg);
            return xmlSerial.write(jsonObj);
        }
    }

    /**
     * 从XML转json串
     *
     * @param xml
     * @return String
     */
    public static String getJsonStrFromXML(String xml) {
        XMLSerializer xmlSerial = new XMLSerializer();
        return String.valueOf(xmlSerial.read(xml));
    }

}

/**
 * json日期值处理器实现
 */
class JsonDateValueProcessor implements JsonValueProcessor {

    private String format = "yyyyMMddHHmmss";

    public JsonDateValueProcessor() {

    }

    public JsonDateValueProcessor(String format) {
        this.format = format;
    }

    public Object processArrayValue(Object value, JsonConfig jsonConfig) {
        return process(value, jsonConfig);
    }

    public Object processObjectValue(String key, Object value,
                                     JsonConfig jsonConfig) {
        return process(value, jsonConfig);
    }

    private Object process(Object value, JsonConfig jsonConfig) {
        if (value instanceof Date) {
            String str = new SimpleDateFormat(format).format((Date) value);
            return str;
        }
        return value == null ? null : value.toString();
    }

    public String getFormat() {
        return format;
    }

    public void setFormat(String format) {
        this.format = format;
    }

}